package com.ruoyi.central.publisher.subscription.task.cmd.run;

import com.ruoyi.central.domain.TopCentralTaskCmd;
import com.ruoyi.central.domain.TopCentralTaskCmdRun;
import com.ruoyi.central.enums.OperationTypeEnum;
import com.ruoyi.central.publisher.event.TaskCmdRunEvent;
import com.ruoyi.central.service.ITopCentralTaskCmdRunService;
import com.ruoyi.central.service.ITopCentralTaskCmdService;
import com.ruoyi.central.utils.CmdInvokeUtil;
import com.ruoyi.common.enums.common.TaskStatusEnum;
import com.ruoyi.common.exception.base.service.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.EnumUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.text.MessageFormat;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

/**
 * @Classname TaskCmdRunEventSubscription
 * @Author: sunluquan
 * @Date: 2022/6/13 14:44
 * @Description TODO
 * 任务指令执行 相关 事件 订阅对象
 */
@Component
@Slf4j
public class TaskCmdRunEventSubscription {

    @Autowired
    private ITopCentralTaskCmdRunService taskCmdRunService;

    @Autowired
    private ITopCentralTaskCmdService taskCmdService;
    /**
     * 1.如果修改执行任务状态 并且 为自动执行类型 且 executable 有值
     * 2.如果满足第一步  执行 executable
     * 3.判断任务执行状态是否要修改 为 完成
     * 4.如果修改为完成 则需要判断下一条指令是否为 自动操作类型  如果为手动操作类型 设置状态为执行中
     * @param event
     */
    @EventListener(value=TaskCmdRunEvent.class,condition = "#event.getSignEnum().name() == 'UPDATE'")
    public void updateEvent(TaskCmdRunEvent event) throws Exception {
        TopCentralTaskCmdRun source = event.getSource();

        Integer taskStatusOfNew = source.getTaskStatus();
        Integer taskCmdRunId = source.getId();

        if(StringUtils.isNotNull(taskStatusOfNew)){

            TopCentralTaskCmdRun taskCmdRun = null;
            Integer taskStatusOfOld = null;
            TopCentralTaskCmd taskCmd = null;

            taskCmdRun = taskCmdRunService.selectUsableById(taskCmdRunId);

            Assert.notNull(taskCmdRun, MessageFormat.format("任务指令执行编号：{} 数据未找到或不可用！",taskCmdRunId));

            taskStatusOfOld = taskCmdRun.getTaskStatus();

            taskCmd = taskCmdService.selectAllMap().get(taskCmdRun.getTaskCmdId());

            Assert.notNull(taskCmd, MessageFormat.format("任务指令执行编号：{} 未找到绑定的任务指令数据或数据不可用！",taskCmdRunId));

            taskCmdRun.setTaskCmd(taskCmd);

            log.info("database taskCmdRun -- taskStatus:{} , interface taskCmdRun -- taskStatus:{}",taskStatusOfOld,taskStatusOfNew);

            if(!StringUtils.equals(taskStatusOfNew,taskStatusOfOld)){


                if(!EnumUtils.toEnum(TaskStatusEnum.class,taskStatusOfOld).isTransition(EnumUtils.toEnum(TaskStatusEnum.class,taskStatusOfNew))){

                    TaskStatusEnum taskStatusTarget = EnumUtils.toEnum(TaskStatusEnum.class,taskStatusOfNew);

                    TaskStatusEnum taskStatusSource = EnumUtils.toEnum(TaskStatusEnum.class,taskStatusOfOld);

                    throw new ServiceException("{} 状态不能过渡到 {}状态！",taskStatusSource,taskStatusTarget);

                }

                if(//EnumUtils.equals(TaskStatusEnum.EXECUTING,taskStatusOfNew)
//                        EnumUtils.equals(OperationTypeEnum.AUTOMATIC_TYPE,taskCmd.getType())
//                                &&
                                StringUtils.isNotEmpty(taskCmd.getExecutable())){

                    CmdInvokeUtil.invokeMethod(taskCmdRun);

                }
                if(EnumUtils.equals(TaskStatusEnum.EXECUTED_FINISH,taskStatusOfNew)){

                    Integer processStepRunId = source.getProcessStepRunId();
                    Assert.notNull(processStepRunId,StringUtils.format( "当前指令：{}，执行工序不能为空！",taskCmd.getName()));

                    List<TopCentralTaskCmdRun> taskCmdRuns = taskCmdRunService.selectByProcessStepRunId(processStepRunId);

                    Assert.notEmpty(taskCmdRuns,StringUtils.format( "当前指令：{}，执行指令绑定执行工序丢失！",taskCmd.getName()));

                    if(taskCmdRuns.size()>1){
                        //获取当前指令对象的 下一个指令对象
                        TopCentralTaskCmdRun nextTaskCmdRun = null;

                        taskCmdRuns.sort(Comparator.comparing(TopCentralTaskCmdRun::getWeight));

                        Iterator<TopCentralTaskCmdRun> iterator = taskCmdRuns.iterator();
                        while(iterator.hasNext()){
                            if(StringUtils.equals(iterator.next().getId(),taskCmdRunId)){
                                if(iterator.hasNext()){
                                    nextTaskCmdRun = iterator.next();
                                }
                            }
                        }
                        //如果当前指令任务  还有下一个任务 并且下一个任务为手动操作类型
                        if(StringUtils.isNotNull(nextTaskCmdRun) &&
                                EnumUtils.equals(OperationTypeEnum.MANUAL_TYPE,nextTaskCmdRun.getTaskCmd().getType())){
                            TopCentralTaskCmdRun taskCmdRunOfUpdate = new TopCentralTaskCmdRun();
                            taskCmdRunOfUpdate.setId(nextTaskCmdRun.getId());
                            taskCmdRunOfUpdate.setTaskStatus(TaskStatusEnum.EXECUTING.getValue());

                            taskCmdRunService.updateById(taskCmdRunOfUpdate);
                        }
                    }
                }
            }
        }
    }
}
